package com.techysky.util;

/*
Java web 项目中对数据库备份和恢复
2018年04月30日 19:39:18 蓝星花 阅读数：948 标签： java 数据库备份与还原  更多
个人分类： 后端编程
版权声明：本文为博主原创文章，未经博主允许不得转载。	https://blog.csdn.net/m0_37499059/article/details/80151409
说白了，还是去调用cmd实现数据库的备份和还原功能。

备份：

mysqldump -hserverUrl -uusername -ppassword dbname > savePath
还原：

mysql -hserverUrl -uusername -ppassword dbname < filePath

*/
 
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
 
/**
 * @Author: cxx
 * 数据库备份与还原
 * @Date: 2018/4/28 19:56
 */
public class DbOperate {

	/**
     * @param hostIP ip地址，可以是本机也可以是远程
     * @param userName 数据库的用户名
     * @param password 数据库的密码
     * @param savePath 备份的路径
     * @param fileName 备份的文件名
     * @param databaseName 需要备份的数据库的名称
     * @return
	 * @throws Exception 
     */

    public static void backup(String hostIP, String userName, String password, String savePath, String fileName,
			String databaseName) throws Exception {
		File saveFile = new File(savePath+fileName);
		if (!saveFile.exists()) {// 如果目录不存在
			saveFile.createNewFile();
		}
		
		//if (!savePath.endsWith(File.separator)) { savePath = savePath + File.separator; }
		 

		// 拼接命令行的命令
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append("mysqldump").append(" --opt").append(" -h")
				.append(hostIP);
		stringBuilder.append(" --user=").append(userName)
				.append(" --password=").append(password)
				.append(" --lock-all-tables=true");
		stringBuilder.append(" --result-file=").append(savePath + fileName)
				.append(" --default-character-set=utf8 ").append(databaseName);
		try {
			// 调用外部执行exe文件的javaAPI
			System.out.println("cmd命令为：" + stringBuilder.toString());
			System.out.println("开始备份：" + databaseName);
			Process process = Runtime.getRuntime().exec(
					stringBuilder.toString());
			InputStream is = process.getInputStream();
			BufferedReader bf = new BufferedReader(new InputStreamReader(is,
					"utf8"));
			String line = null;
			while ((line = bf.readLine()) != null) {
				System.out.println(line);
			}
			File file = new File(savePath + fileName);
			try {
				security(file, 0xffff);
				System.out.println("备份成功!");
			} catch (Exception e) {
				e.printStackTrace();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
    /**
     * 备份数据库db
     * @param root
     * @param pwd
     * @param dbName
     * @param backPath
     * @param backName
     */
    public static void dbBackUp(String root,String pwd,String dbName,String backPath,String backName,String tables) throws Exception {
        String pathSql = backPath+backName;
        File fileSql = new File(pathSql);
        //创建备份sql文件
        if (!fileSql.exists()){
            fileSql.createNewFile();
        }
        //mysqldump -hlocalhost -uroot -p123456 db > /home/back.sql
        StringBuffer sb = new StringBuffer();
        sb.append("mysqldump");
        sb.append(" --opt -h127.0.0.1 ");
        sb.append(" --lock-all-tables=true ");
        sb.append(" -u"+root);
        sb.append(" -p"+pwd);
        sb.append(" -d "+dbName);
        sb.append(" "+tables+" > ");
        sb.append(pathSql);
        System.out.println("cmd命令为："+sb.toString());
        Runtime runtime = Runtime.getRuntime();
        System.out.println("开始备份："+dbName);
        Process process = runtime.exec("cmd /c"+sb.toString());
        InputStream is =  process.getInputStream();
        BufferedReader bf = new BufferedReader(new InputStreamReader(is,"utf8"));
        String line = null;
        while ((line=bf.readLine())!=null){
            System.out.println(line);
        }
        File file = new File(pathSql);
        if(file.length()>0)
        {
        	 security(file,0xffff);
        }
        System.out.println("备份成功!");
    }
 
    /**
     * 恢复数据库
     * @param root
     * @param pwd
     * @param dbName
     * @param filePath
     * mysql -hlocalhost -uroot -p123456 db < /home/back.sql
     * @throws Exception 
     */
    public static void dbRestore(String root,String pwd,String dbName,String filePath) throws Exception{
    	File file = new File(filePath);
    	//security(file,0xffff);
    	File target =new File(file.getAbsolutePath().substring(0,file.getAbsolutePath().indexOf('.'))+"-techysky"+file.getAbsolutePath().substring(file.getAbsolutePath().indexOf('.')));
		 if(!target.exists()&&target.createNewFile()){}
		 DecFile(file,target,0xffff);
		 Files.delete(file.toPath());
 		 if(target.renameTo(file)) {
 		 }
        StringBuilder sb = new StringBuilder();
        sb.append("mysql");
        sb.append(" -h127.0.0.1");
        sb.append(" -u"+root);
        sb.append(" -p"+pwd);
        sb.append(" "+dbName+" < ");
        sb.append(target);
        System.out.println("cmd命令为："+sb.toString());
        Runtime runtime = Runtime.getRuntime();
        System.out.println("开始还原数据");
        Process process = runtime.exec("cmd /c"+sb.toString());
            InputStream is = process.getInputStream();
            BufferedReader bf = new BufferedReader(new InputStreamReader(is,"utf8"));
            String line = null;
            System.out.println(bf.readLine());
            while ((line=bf.readLine())!=null){
                System.out.println(line);
            }
            is.close();
            bf.close();

        System.out.println("还原成功！");
    }
    public static void main(String[] args) throws Exception {
        String backName = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date())+".sql";
        //DbOperate.backup("127.0.0.1", "root", "123456", "E:/lingang/", backName, "lin");
        //DbOperate.dbBackUp("root","123456","lingang","E:/lingang/",backName,"");
        //dbRestore("root","123456","lingang","E:/lingang/2018-09-29-11-44-01.sql");
        //recover("E:/lingang/2018-09-29-11-52-15.sql","127.0.0.1","lingang","root","123456");
        DbOperate db = new DbOperate();
        //db.dbClean("lingang");
       // dbClean("lingang");
    }
 
	private static void DecFile(File encFile, File decFile,int key) throws Exception {
	  if(!encFile.exists()){
	 System.out.println("encrypt file not exixt");
	 return;}
	 
	 if(!decFile.exists()){
	 System.out.println("decrypt file created");
	 decFile.createNewFile();}
	 
	 InputStream fis  = new FileInputStream(encFile);
	 OutputStream fos = new FileOutputStream(decFile);
	 int init=0;
	 while ((init = fis.read()) > -1) {
	 fos.write(init^key);
	}
	 
	 fis.close();
	 fos.flush();
	 fos.close();
	 encFile.delete();
	 }
   
    
    public static void security(File src,int key) throws Exception {
     	 if(!src.exists()){
     		return ;
          }
     	 try {
     		 File target =new File(src.getAbsolutePath().substring(0,src.getAbsolutePath().indexOf('.'))+"-techysky"+src.getAbsolutePath().substring(src.getAbsolutePath().indexOf('.')));
     		 if(!target.exists()&&target.createNewFile()){}
     		 convertFile(src,target,key);
     		 Files.delete(src.toPath()) ;
     		 if(target.renameTo(src)) {
     		 }
  			} catch (IOException e) {
  			}
     }
    
    /**
     * 
     * @param srcFile
     * @param encFile
     */
    private static   void convertFile(File src, File target,int key)  {
    	int init=0;
    	try(InputStream fis  = new FileInputStream(src);OutputStream fos = new FileOutputStream(target)) {
    		  while ((init = fis.read()) > -1) {
    			  fos.write(init^key);
    		  }
    		  fos.flush();
    		  fis.close();
    		  fos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
    }
}
